<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    . 简单的语法
        ● const 与 let   与var的区别
          const定义常量, let和var定义变量
          是否有块作用
          是否有变量提升
          全局变量是否会添加到window
          是否可以重复声明
        ● 解构赋值
        ● 形参默认值
        ● 扩展运算符: ...
        ● 模板字符串
        ● 对象的属性与方法简写
        ● 模块化语法
        ● 箭头函数（延伸总结 this 指向）
            优点: 编码简洁
            特点: 
              没有自己的this, 不能通过call/bind指定this
              不能通过new来创建实例对象
              函数内部没有arguments(代表实参列表的伪数组), 可以通过rest参数来代替  (...args)  args所有实参列表的真数组
      2. 比较复杂的语法
        ● class 与 extend（延伸原型和继承）
        ● promise / generator / async & await（延伸 js 事件循环机制）
        ● Proxy（延伸 vue2 和 vue3 响应式原理）
            vue2中使用Object.defineProperty来实现数据劫持的响应式
            vue3中使用Proxy来实现数据劫持的响应式
            区别: 
              defineProperty: 以对象中的属性为单位来劫持 读取/修改
              Proxy: 以对象为单位来劫持 读取/修改/   添加/删除
              => Proxy能力更强, 性能更高

        ● Map / Set / WeakMap / WeakSet (延伸 vue3 响应式原理)
            Map: 类似于对象, 保存多个key-value   有序, key是唯一, value不是   key和value可以任意类型 (对象的属性名只能是string/symbol)
            Set: 类似于数组, 保存多个value  有序/value是唯一的  value可以是任意类型
            WeakMap: 是特别的Map, key只能是对象, 容器对内部的key是一个弱引用, 
                  一旦没有外部引用指向key对象时, key-value有可能会被自动从容器清除, 但Map是不会 
                  weakMap可以作为优化后的容器 => vue3内部的响应式实现用到了weakMap
    */

    const map = new Map()
    let obj = {m: 1}
    map.set(obj, 3)
    obj = null
    console.log(map, map.get(obj))

    const map2 = new WeakMap()
    let obj2 = {m: 2}
    map2.set(obj2, 'abc')
    obj2 = null
    console.log(map2)


  </script>
</body>
</html>